import * as Cesium from 'cesium';

export class Provider {
  constructor(cesiumManager) {
    this.cesiumManager = cesiumManager;
    this.terrainProviders = new Map();
    this.imageryProviders = new Map();
  }

  /**
   * 添加地形提供者
   * @param {String} name - 地形提供者名称
   * @param {Object} options - 地形提供者选项
   * @returns {TerrainProvider} 创建的地形提供者
   */
  addTerrainProvider(name, options = {}) {
    if (!this.cesiumManager || !this.cesiumManager.viewer) {
      throw new Error('Cesium manager or viewer is not initialized');
    }

    const viewer = this.cesiumManager.viewer;
    let terrainProvider;

    switch (options.type) {
      case 'cesium-world':
        terrainProvider = Cesium.createWorldTerrainAsync({
          requestWaterMask: options.requestWaterMask || true,
          requestVertexNormals: options.requestVertexNormals || true
        });
        break;
        
      case 'ellipsoid':
        terrainProvider = new Cesium.EllipsoidTerrainProvider();
        break;
        
      case 'cesium-tile-map':
        terrainProvider = new Cesium.CesiumTerrainProvider({
          url: options.url || Cesium.IonResource.fromAssetId(1),
          requestWaterMask: options.requestWaterMask || true,
          requestVertexNormals: options.requestVertexNormals || true
        });
        break;
        
      default:
        throw new Error('Unsupported terrain provider type');
    }

    this.terrainProviders.set(name, terrainProvider);
    
    // 如果指定了设为当前地形
    if (options.setCurrent !== false) {
      viewer.terrainProvider = terrainProvider;
    }

    return terrainProvider;
  }

  /**
   * 获取地形提供者
   * @param {String} name - 地形提供者名称
   * @returns {TerrainProvider|undefined} 地形提供者对象
   */
  getTerrainProvider(name) {
    return this.terrainProviders.get(name);
  }

  /**
   * 设置当前地形提供者
   * @param {String|TerrainProvider} nameOrProvider - 地形提供者名称或实例
   */
  setCurrentTerrainProvider(nameOrProvider) {
    if (!this.cesiumManager || !this.cesiumManager.viewer) {
      throw new Error('Cesium manager or viewer is not initialized');
    }

    const viewer = this.cesiumManager.viewer;
    let terrainProvider;

    if (typeof nameOrProvider === 'string') {
      terrainProvider = this.terrainProviders.get(nameOrProvider);
      if (!terrainProvider) {
        throw new Error(`Terrain provider "${nameOrProvider}" not found`);
      }
    } else {
      terrainProvider = nameOrProvider;
    }

    viewer.terrainProvider = terrainProvider;
  }

  /**
   * 移除地形提供者
   * @param {String} name - 地形提供者名称
   */
  removeTerrainProvider(name) {
    this.terrainProviders.delete(name);
  }

  /**
   * 添加影像提供者
   * @param {String} name - 影像提供者名称
   * @param {Object} options - 影像提供者选项
   * @returns {ImageryLayer} 创建的影像图层
   */
  addImageryProvider(name, options = {}) {
    if (!this.cesiumManager || !this.cesiumManager.viewer) {
      throw new Error('Cesium manager or viewer is not initialized');
    }

    const viewer = this.cesiumManager.viewer;
    let imageryProvider;
    let imageryLayer;

    switch (options.type) {
      case 'bing-maps':
        imageryProvider = new Cesium.BingMapsImageryProvider({
          url: 'https://dev.virtualearth.net',
          key: options.key || '',
          mapStyle: options.mapStyle || Cesium.BingMapsStyle.AERIAL
        });
        break;
        
      case 'open-street-map':
        imageryProvider = new Cesium.OpenStreetMapImageryProvider({
          url: options.url || 'https://a.tile.openstreetmap.org/'
        });
        break;
        
      case 'arcgis-map-server':
        imageryProvider = new Cesium.ArcGisMapServerImageryProvider({
          url: options.url
        });
        break;
        
      case 'tile-map-service':
        imageryProvider = new Cesium.TileMapServiceImageryProvider({
          url: options.url
        });
        break;
        
      case 'web-map-service':
        imageryProvider = new Cesium.WebMapServiceImageryProvider({
          url: options.url,
          layers: options.layers || '',
          parameters: options.parameters || {}
        });
        break;
        
      case 'ion':
        imageryProvider = new Cesium.IonImageryProvider({
          assetId: options.assetId
        });
        break;
        
      case 'single-tile':
        imageryProvider = new Cesium.SingleTileImageryProvider({
          url: options.url
        });
        break;
        
      case 'url-template':
        imageryProvider = new Cesium.UrlTemplateImageryProvider({
          url: options.url,
          subdomains: options.subdomains || [],
          credit: options.credit || ''
        });
        break;
        
      default:
        throw new Error('Unsupported imagery provider type');
    }

    // 创建影像图层
    imageryLayer = viewer.imageryLayers.addImageryProvider(imageryProvider, options.index);
    
    // 设置图层属性
    if (options.alpha !== undefined) {
      imageryLayer.alpha = options.alpha;
    }
    
    if (options.show !== undefined) {
      imageryLayer.show = options.show;
    }
    
    if (options.brightness !== undefined) {
      imageryLayer.brightness = options.brightness;
    }
    
    if (options.contrast !== undefined) {
      imageryLayer.contrast = options.contrast;
    }
    
    if (options.gamma !== undefined) {
      imageryLayer.gamma = options.gamma;
    }

    this.imageryProviders.set(name, {
      provider: imageryProvider,
      layer: imageryLayer
    });

    return imageryLayer;
  }

  /**
   * 获取影像提供者
   * @param {String} name - 影像提供者名称
   * @returns {Object|undefined} 影像提供者和图层对象
   */
  getImageryProvider(name) {
    return this.imageryProviders.get(name);
  }

  /**
   * 更新影像图层属性
   * @param {String} name - 影像提供者名称
   * @param {Object} options - 要更新的属性
   */
  updateImageryLayer(name, options) {
    const imageryData = this.imageryProviders.get(name);
    if (!imageryData) {
      throw new Error(`Imagery provider "${name}" not found`);
    }

    const imageryLayer = imageryData.layer;

    if (options.alpha !== undefined) {
      imageryLayer.alpha = options.alpha;
    }
    
    if (options.show !== undefined) {
      imageryLayer.show = options.show;
    }
    
    if (options.brightness !== undefined) {
      imageryLayer.brightness = options.brightness;
    }
    
    if (options.contrast !== undefined) {
      imageryLayer.contrast = options.contrast;
    }
    
    if (options.gamma !== undefined) {
      imageryLayer.gamma = options.gamma;
    }
    
    if (options.hue !== undefined) {
      imageryLayer.hue = options.hue;
    }
    
    if (options.saturation !== undefined) {
      imageryLayer.saturation = options.saturation;
    }
  }

  /**
   * 移除影像提供者
   * @param {String} name - 影像提供者名称
   */
  removeImageryProvider(name) {
    const imageryData = this.imageryProviders.get(name);
    if (imageryData && this.cesiumManager && this.cesiumManager.viewer) {
      this.cesiumManager.viewer.imageryLayers.remove(imageryData.layer);
    }
    this.imageryProviders.delete(name);
  }

  /**
   * 调整影像图层顺序
   * @param {String} name - 影像提供者名称
   * @param {Number} newIndex - 新的图层索引
   */
  reorderImageryLayer(name, newIndex) {
    const imageryData = this.imageryProviders.get(name);
    if (!imageryData) {
      throw new Error(`Imagery provider "${name}" not found`);
    }

    if (!this.cesiumManager || !this.cesiumManager.viewer) {
      throw new Error('Cesium manager or viewer is not initialized');
    }

    const viewer = this.cesiumManager.viewer;
    viewer.imageryLayers.raiseToTop(imageryData.layer);
  }

  /**
   * 获取所有影像图层
   * @returns {Array} 所有影像图层数组
   */
  getAllImageryLayers() {
    if (!this.cesiumManager || !this.cesiumManager.viewer) {
      throw new Error('Cesium manager or viewer is not initialized');
    }

    return this.cesiumManager.viewer.imageryLayers;
  }

  /**
   * 清除所有影像图层
   */
  clearAllImageryLayers() {
    if (!this.cesiumManager || !this.cesiumManager.viewer) {
      throw new Error('Cesium manager or viewer is not initialized');
    }

    const viewer = this.cesiumManager.viewer;
    viewer.imageryLayers.removeAll();
    this.imageryProviders.clear();
  }

  /**
   * 销毁所有资源
   */
  destroy() {
    this.terrainProviders.clear();
    this.imageryProviders.clear();
  }
}